package io.jboot.fly.service.impl;

import com.jfinal.kit.Ret;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.IAtom;
import com.jfinal.plugin.activerecord.Page;
import io.jboot.aop.annotation.Bean;
import io.jboot.db.model.Columns;
import io.jboot.fly.FlyConfig;
import io.jboot.fly.model.Comment;
import io.jboot.fly.model.Post;
import io.jboot.fly.model.User;
import io.jboot.fly.model.UserAction;
import io.jboot.fly.service.CommentService;
import io.jboot.fly.service.PostService;
import io.jboot.fly.service.UserActionService;
import io.jboot.fly.service.UserService;
import io.jboot.service.JbootServiceBase;

import javax.inject.Inject;
import javax.inject.Singleton;
import java.sql.SQLException;
import java.util.List;

@Bean
@Singleton
public class CommentServiceImpl extends JbootServiceBase<Comment> implements CommentService {

    @Inject
    private PostService postService;

    @Inject
    private UserService userService;

    @Inject
    private UserActionService userActionService;

    @Inject
    private CommentService commentService;

    @Override
    public Ret doAdoptComment(String commentId, int starNum) {

        Comment comment = findById(commentId);
        if (comment == null) {
            return Ret.fail("message", "ID数据错误");
        }


        Post post = postService.findById(comment.getPostId());
        if (post == null) {
            return Ret.fail("message", "ID数据错误");
        }

        //已经结帖了
        if (post.isFinished()) {
            return Ret.fail("message", "已经结帖了");
        }

        post.setStatus(Post.STATUS_FINISHED); //设置帖子为：已经结帖
        comment.setStatus(Comment.STATUS_ADOPTED); //设置该条回复为：被采纳

        boolean success = Db.tx(new IAtom() {
            @Override
            public boolean run() throws SQLException {
                if (!post.update()) {
                    return false;
                }
                if (!comment.update()) {
                    return false;
                }


                // 结帖用户得分
                int finishedPostPoint = FlyConfig.get().getFinishedPostPoint();
                if (!userService.changePoint(post.getUserId(), finishedPostPoint)) {
                    return false;
                }

                UserAction finishedPostAction = new UserAction();
                finishedPostAction.setAction(UserAction.ACTION_FINISHED_POST);
                finishedPostAction.setUserId(post.getUserId());
                finishedPostAction.setPostId(post.getId());
                finishedPostAction.setPoint(finishedPostPoint);

                if (!userActionService.save(finishedPostAction)) {
                    return false;
                }


//                //被采纳用户得分 (old)
//                if (!userService.changePoint(comment.getUserId(), post.getPayPoint())) {
//                    return false;
//                }
                //被采纳用户得分
                if (!userService.changePoint(comment.getUserId(), starNum)) {
                    return false;
                }
                UserAction adoptComment = new UserAction();
                adoptComment.setAction(UserAction.ACTION_COMMENT_ADOPTED);
                adoptComment.setUserId(comment.getUserId());
                adoptComment.setPostId(post.getId());
                adoptComment.setCommentId(commentId);
//                adoptComment.setPoint(finishedPostPoint);
                adoptComment.setPoint(starNum);

                if (!userActionService.save(adoptComment)) {
                    return false;
                }


                return true;
            }
        });

        return success ? Ret.ok() : Ret.fail("message", "系统错误，请稍后再试");
    }

    @Override
    public Ret doZanComment(String commentId, User user) {

        Comment comment = findById(commentId);
        if (comment == null) {
            return Ret.fail("message", "ID数据错误");
        }

        Post post = postService.findById(comment.getPostId());
        if (post == null) {
            return Ret.fail("message", "ID数据错误");
        }

        //已经结帖了
        if (post.isFinished()) {
            return Ret.fail("message", "已经结帖了");
        }

        //判断是否已被点赞或鄙视
        List<UserAction> actionZan = userActionService.findByUserIdCommentIdAction(user.getId(), commentId, UserAction.ACTION_COMMENT_ZAN);
        List<UserAction> actionDespise = userActionService.findByUserIdCommentIdAction(user.getId(), commentId, UserAction.ACTION_COMMENT_DESPISED);
        String status_zan_or_despise = null;
        if (actionZan.isEmpty() && actionDespise.isEmpty()) {
            status_zan_or_despise = Comment.STATUS_NO_ZAN_NO_DESPISE;
        } else if (!actionZan.isEmpty() && actionDespise.isEmpty()) {
            status_zan_or_despise = Comment.STATUS_ZAN_NO_DESPISE;
        } else if (actionZan.isEmpty() && !actionDespise.isEmpty()) {
            status_zan_or_despise = Comment.STATUS_NO_ZAN_DESPISE;
        }
        boolean success = Db.tx(new IAtom() {
            @Override
            public boolean run() throws SQLException {
                int zanCommentPoint = FlyConfig.get().getZanCommentPoint();
                if (actionZan.isEmpty() && actionDespise.isEmpty()) {
                    //被点赞评论人得分（+1）
                    if (!userService.changePoint(comment.getUserId(), zanCommentPoint)) {
                        return false;
                    }
                    UserAction zanComment = new UserAction();
                    zanComment.setAction(UserAction.ACTION_COMMENT_ZAN);
                    zanComment.setUserId(user.getId());    // 记录评论人
                    zanComment.setPostId(post.getId());
                    zanComment.setCommentId(commentId);
                    zanComment.setPoint(zanCommentPoint);
                    if (!userActionService.save(zanComment)) {
                        return false;
                    }
                    //更新被点赞值
                    if (!commentService.changeVoteUp(commentId, zanCommentPoint)) {
                        return false;
                    }
                } else if (!actionZan.isEmpty() && actionDespise.isEmpty()) {
                    //已点赞要取消 评论人减分
                    if (!userService.changePoint(comment.getUserId(), (-zanCommentPoint))) {
                        return false;
                    }
                    UserAction zanComment = new UserAction();
                    zanComment.setAction(UserAction.ACTION_COMMENT_ZAN_CONSOLE);
                    zanComment.setUserId(user.getId());
                    zanComment.setPostId(post.getId());
                    zanComment.setCommentId(commentId);
                    zanComment.setPoint(zanCommentPoint);
                    if (!userActionService.save(zanComment)) {
                        return false;
                    }
                    //更新被点赞值
                    if (!commentService.changeVoteUp(commentId, (-zanCommentPoint))) {
                        return false;
                    }
                    //删掉点赞记录
                    if (!userActionService.deleteByUserIdCommentIdAction(user.getId(), commentId, UserAction.ACTION_COMMENT_ZAN)) {
                        return false;
                    }
                } else if (actionZan.isEmpty() && !actionDespise.isEmpty()) {
                    //由鄙视转为点赞
                    if (!userService.changePoint(comment.getUserId(), (2*zanCommentPoint))) {
                        return false;
                    }
                    UserAction zanComment = new UserAction();
                    zanComment.setAction(UserAction.ACTION_COMMENT_DESPISED_TO_ZAN);
                    zanComment.setUserId(user.getId());
                    zanComment.setPostId(post.getId());
                    zanComment.setCommentId(commentId);
                    zanComment.setPoint(2*zanCommentPoint);
                    if (!userActionService.save(zanComment)) {
                        return false;
                    }
                    UserAction zanComment_new_despise = new UserAction();
                    zanComment_new_despise.setAction(UserAction.ACTION_COMMENT_ZAN);
                    zanComment_new_despise.setUserId(user.getId());
                    zanComment_new_despise.setPostId(post.getId());
                    zanComment_new_despise.setCommentId(commentId);
                    zanComment_new_despise.setPoint(zanCommentPoint);
                    if (!userActionService.save(zanComment_new_despise)) {
                        return false;
                    }
                    //更新被点赞值
                    if (!commentService.changeVoteUp(commentId, zanCommentPoint)) {
                        return false;
                    }
                    if (!commentService.changeVoteDown(commentId, (-zanCommentPoint))) {
                        return false;
                    }
                    //删掉鄙视记录
                    if (!userActionService.deleteByUserIdCommentIdAction(user.getId(), commentId, UserAction.ACTION_COMMENT_DESPISED)) {
                        return false;
                    }
                } else {
                    return false;
                }
                return true;
            }
        });

        return success ? Ret.ok().set("status_zan_or_despise", status_zan_or_despise): Ret.fail("message", "系统错误，请稍后再试");
    }

    @Override
    public Ret doDespiseComment(String commentId, User user) {

        Comment comment = findById(commentId);
        if (comment == null) {
            return Ret.fail("message", "ID数据错误");
        }

        Post post = postService.findById(comment.getPostId());
        if (post == null) {
            return Ret.fail("message", "ID数据错误");
        }

        //已经结帖了
        if (post.isFinished()) {
            return Ret.fail("message", "已经结帖了");
        }

        //判断是否已被鄙视或点赞
        List<UserAction> actionDespise = userActionService.findByUserIdCommentIdAction(user.getId(), commentId, UserAction.ACTION_COMMENT_DESPISED);
        List<UserAction> actionZan = userActionService.findByUserIdCommentIdAction(user.getId(), commentId, UserAction.ACTION_COMMENT_ZAN);
        String status_zan_or_despise = null;
        if (actionDespise.isEmpty() && actionZan.isEmpty()) {
            status_zan_or_despise = Comment.STATUS_NO_ZAN_NO_DESPISE;
        } else if (!actionDespise.isEmpty() && actionZan.isEmpty()) {
            status_zan_or_despise = Comment.STATUS_NO_ZAN_DESPISE;
        } else if (actionDespise.isEmpty() && !actionZan.isEmpty()) {
            status_zan_or_despise = Comment.STATUS_ZAN_NO_DESPISE ;
        }
        boolean success = Db.tx(new IAtom() {
            @Override
            public boolean run() throws SQLException {
                int despiseCommentPoint = FlyConfig.get().getDespiseCommentPoint();
                if (actionDespise.isEmpty() && actionZan.isEmpty()) {
                    //被鄙视评论人得分（-1）
                    if (!userService.changePoint(comment.getUserId(), (-despiseCommentPoint))) {
                        return false;
                    }
                    UserAction despiseComment = new UserAction();
                    despiseComment.setAction(UserAction.ACTION_COMMENT_DESPISED);
                    despiseComment.setUserId(user.getId());    // 记录评论人
                    despiseComment.setPostId(post.getId());
                    despiseComment.setCommentId(commentId);
                    despiseComment.setPoint(despiseCommentPoint);
                    if (!userActionService.save(despiseComment)) {
                        return false;
                    }
                    //更新被鄙视值
                    if (!commentService.changeVoteDown(commentId, despiseCommentPoint)) {
                        return false;
                    }
                } else if (!actionDespise.isEmpty() && actionZan.isEmpty()) {
                    //已鄙视要取消 评论人加分
                    if (!userService.changePoint(comment.getUserId(), (despiseCommentPoint))) {
                        return false;
                    }
                    UserAction despiseComment = new UserAction();
                    despiseComment.setAction(UserAction.ACTION_COMMENT_ZAN_CONSOLE);
                    despiseComment.setUserId(user.getId());
                    despiseComment.setPostId(post.getId());
                    despiseComment.setCommentId(commentId);
                    despiseComment.setPoint(despiseCommentPoint);
                    if (!userActionService.save(despiseComment)) {
                        return false;
                    }
                    //更新被鄙视值
                    if (!commentService.changeVoteDown(commentId, (-despiseCommentPoint))) {
                        return false;
                    }
                    //删掉鄙视记录
                    if (!userActionService.deleteByUserIdCommentIdAction(user.getId(), commentId, UserAction.ACTION_COMMENT_DESPISED)) {
                        return false;
                    }
                } else if (actionDespise.isEmpty() && !actionZan.isEmpty()) {
                    //由点赞转为鄙视
                    if (!userService.changePoint(comment.getUserId(), (-2*despiseCommentPoint))) {
                        return false;
                    }
                    UserAction despiseComment = new UserAction();
                    despiseComment.setAction(UserAction.ACTION_COMMENT_ZAN_TO_DESPISED);
                    despiseComment.setUserId(user.getId());
                    despiseComment.setPostId(post.getId());
                    despiseComment.setCommentId(commentId);
                    despiseComment.setPoint(2*despiseCommentPoint);
                    if (!userActionService.save(despiseComment)) {
                        return false;
                    }
                    UserAction despiseComment_new_despise = new UserAction();
                    despiseComment_new_despise.setAction(UserAction.ACTION_COMMENT_DESPISED);
                    despiseComment_new_despise.setUserId(user.getId());
                    despiseComment_new_despise.setPostId(post.getId());
                    despiseComment_new_despise.setCommentId(commentId);
                    despiseComment_new_despise.setPoint(despiseCommentPoint);
                    if (!userActionService.save(despiseComment_new_despise)) {
                        return false;
                    }
                    //更新被点赞值
                    if (!commentService.changeVoteUp(commentId, (-despiseCommentPoint))) {
                        return false;
                    }
                    if (!commentService.changeVoteDown(commentId, despiseCommentPoint)) {
                        return false;
                    }
                    //删掉鄙视记录
                    if (!userActionService.deleteByUserIdCommentIdAction(user.getId(), commentId, UserAction.ACTION_COMMENT_ZAN)) {
                        return false;
                    }
                } else {
                    return false;
                }
                return true;
            }
        });

        return success ? Ret.ok().set("status_zan_or_despise", status_zan_or_despise): Ret.fail("message", "系统错误，请稍后再试");
    }

    @Override
    public Page<Comment> paginateByPostId(int pageNumber, int pageSize, String postId) {
        Columns columns = Columns.create("post_id", postId).ge("status", 0);
        return DAO.paginateByColumns(pageNumber, pageSize, columns.getList(), "created desc");
    }

    @Override
    public boolean changeVoteUp(String commentId, int point) {
        String sql = "update `comment` SET vote_up = vote_up + ? where id = ? ";
        return Db.update(sql, point, commentId) > 0;
    }

    @Override
    public boolean changeVoteDown(String commentId, int point) {
        String sql = "update `comment` SET vote_down = vote_down + ? where id = ? ";
        return Db.update(sql, point, commentId) > 0;
    }
}